home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
lcppb.zip
/
LCPPLIB.ZIP
/
WINDOW.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-08
|
12KB
|
325 lines
// window.cpp -- Window class
//#include <disp.h>
#include "disp.h"
#include <stdlib.h>
#include <string.h>
#include "error.h"
#include "window.h"
#define FALSE 0
#define TRUE 1
extern disp_numrows; // Gain access to normally hidden
extern disp_numcols; // display package variables.
/* -- Define and initialize the static class member field, which
indicates whether the display package has been initialized. This
variable is global--it is shared by all variables of the cwindow
class. But, because it's declared private to the class, only class
member functions have access to it. */
int cwindow::dispInitialized = FALSE;
/* -- Private routine (not a member of the cwindow class). Display a
string at an absolute row and column position using the specified
attribute. Limit length of string to len characters. Ideally, this
routine should display all possible ASCII symbols--it should not
respond to control codes such as carriage returns and line feeds. */
void putsat(int row, int col, int len, unsigned attr, char *s)
{
unsigned char buffer[264];
int i, j;
if (len == 0) return;
for (i = 0, j = 0; i < len; i++, j += 2) {
buffer[j] = s[i];
buffer[j + 1] = attr;
}
disp_pokebox((unsigned *)&buffer, row, col, row, col + len - 1);
}
/* -- Program must call the class static startup function to
initialize the display package (or another display library if porting
the code). Because startup is a static member function, it can access
only static data members of the class. It has no access whatsoever to
other data fields in cwindow class objects. */
void cwindow::startup(void)
{
if (!dispInitialized) { // If not initialized yet
disp_open(); // then initialize display
disp_hidecursor(); // Turn off system cursor
dispInitialized = TRUE; // Set the static flag
}
}
/* -- Program must call the class static shutDown function to
deinitialize the display package. Failure to call this routine could
lead to display problems after the program ends. (This may or may not
be the case after porting the code to a system that doesn't use the
Zortech display package.) */
void cwindow::shutDown(void)
{
if (dispInitialized) { // If previously initialized:
disp_move(disp_numrows - 1, 0 ); // Set cursor to bottom row
disp_showcursor(); // Display cursor
disp_close(); // Shut down display package
dispInitialized = FALSE; // Reset the static flag
}
}
/* -- Create and return pointer to a buffer for saving text behind
window. Returns NULL if enough memory is not available. */
unsigned *cwindow::saveBuf(void)
{
// return malloc((ws.height * ws.width) * sizeof(unsigned));
return (unsigned *)malloc((ws.height * ws.width) * sizeof(unsigned));
}
/* -- Perform various common initialization steps for all new
windows. Called by all class constructors. Aborts program if window
class startup function was not called, or if the class was shut down.
If you add new constructors to the cwindow class, be sure to call this
routine, or failing that, at least test the dispInitialized flag and
take appropriate actions if the flag is false. */
void cwindow::commonInits(void)
{
if (!dispInitialized) // Test if display initialized
error(ERRWININIT); // Halt or report error if not
cr = cc = 0; // Home logical cursor
save = NULL; // Text behind not saved
isOpen = FALSE; // window is not open
if (ws.row > disp_numrows - 3) // Limit smallest window
ws.row = disp_numrows - 3; // to one row, one column
if (ws.col > disp_numcols - 3)
ws.col = disp_numcols - 3;
if (ws.width < 1) ws.width = 1; // window width must be >= 1
if (ws.height < 1) ws.height = 1; // window height must be >= 1
wbr = ws.row + ws.height - 1; // window's bottom row number
wrc = ws.col + ws.width - 1; // window's right column number
wca = ws.wtattr; // Current attr = normal text
wtitle = NULL; // No window title (yet)
}
/* -- Default constructor. Creates full-screen window. The save
pointer is set to NULL, which causes the window not to save the text
behind it. Because the default window is full screen, this saves at
least 4K of memory. */
cwindow::cwindow()
{
ws.row = ws.col = 0; // Upper left corner
ws.width = disp_numcols; // Full width of display
ws.height = disp_numrows; // Full height of display
ws.wtattr = DISP_NORMAL; // Normal text attribute
ws.wbattr = DISP_NORMAL; // Normal border attribute
ws.whattr = DISP_REVERSEVIDEO; // Highlight in reverse video
ws.wtype = 0; // Select double-line border
commonInits(); // Do other init steps
}
/* -- Alternate constructor. Allows sizing window and selecting
various attributes. Saves text behind window. */
cwindow::cwindow(winStruct &ws, const char *title)
{
cwindow::ws = ws;
commonInits();
setTitle(title);
save = saveBuf();
}
/* -- Destructor. Deallocates save-text buffer (if allocated). Note
that it is legal to pass a NULL pointer to free, but it is not okay
to do the same with delete--a minor inconsistency in this version of
C++ that can lead to trouble. Deleting a NULL pointer may cause the
program to crash. */
cwindow::~cwindow()
{
if (isOpen) hideWindow(); // Close window if open
free(save); // Dispose save buffer (if any)
if (wtitle) delete wtitle; // Dispose old title (if any)
}
/* -- Display window outline and title if one was assigned. Called
by showWindow and if the title is changed after window is opened. */
void cwindow::showOutline(void)
{
int len; // String length
disp_box(ws.wtype, ws.wbattr, ws.row, ws.col, wbr, wrc);
if (wtitle != NULL) {
len = strlen(wtitle->getString());
if (len > 0) {
putsat(ws.row, ws.col + ((ws.width - len) / 2), len,
ws.wbattr, wtitle->getString());
gotorc(cr, cc);
}
}
}
/* -- Save text behind window (optional), draw window's border, erase
the contents. Cursor is positioned inside window at top left corner.
The host program is expected to display the window's contents.
Prevents accidentally opening an already open window, which would
destroy the save buffer. */
void cwindow::showWindow()
{
if (isOpen) return; // Prevent multiple openings
if (save) disp_peekbox(save, ws.row, ws.col, wbr, wrc);
showOutline();
isOpen = TRUE;
gotorc(0, 0);
normalVideo();
eeow();
}
/* -- Restore any saved text behind window and mark window closed. If
there is no save buffer, the display will not change, although the
window will still be closed. */
void cwindow::hideWindow()
{
if (!isOpen) return; // Exit if window is closed
if (save) disp_pokebox(save, ws.row, ws.col, wbr, wrc);
isOpen = FALSE;
}
/* -- Change window title. You may call this routine whether or not
you specified a title when creating the window object. window may
be open or closed. */
void cwindow::setTitle(const char *s)
{
if (wtitle) delete wtitle;
wtitle = new strItem(s, ws.width - 2);
if (isOpen) showOutline();
}
/* -- Assign new attributes to window. Use this function to move and
resize windows, or just to change their colors, border types, etc.
Selects normalVideo output. */
void cwindow::setInfo(winStruct &ws)
{
int wasOpen = isOpen;
if (isOpen) hideWindow();
if (save) delete save;
cwindow::ws = ws;
save = saveBuf();
if (wasOpen) {
normalVideo();
showWindow();
}
}
/* -- Move cursor to position inside window border. Top left position
is 0, 0 (home). Row and column values are relative to window
boundaries. Note: Does not make system cursor visible--instead, this
function prepares the location where text will appear for the next
call to puts(). Cursor is allowed to rest on the right border, but
otherwise must remain within the window's boundaries.*/
void cwindow::gotorc(int row, int col)
{
if (!isOpen) return; // Exit if window is closed
cr = row; cc = col; // Save relative values
if (cc < 0) cc = 0; // Prevent negative
if (cr < 0) cr = 0; // cursor positions
if (cc > ws.width - 2)
cc = ws.width - 2; // Limit col to window width
if (cr > ws.height - 3)
cr = ws.height - 3; // Limit row to window height
disp_move(ws.row + cr + 1, ws.col + cc + 1);
}
/* -- Display string at current cursor position. String is truncated
to fit within the window boundaries. Cursor is positioned at the end
of the string. (It is possible for the cursor to be on the
right border, but it is not possible to display text there.) */
void cwindow::puts(char *s)
{
int len = strlen(s); // String length
int nc = ws.width - cc - 2; // Number chars right of cursor
if (!isOpen) return; // Exit if window is closed
if (nc <= 0) return; // Exit if no space to cursor's right
if (len == 0) return; // Exit if length of string is 0
if (len > nc) len = nc; // Truncate too-long strings
putsat(ws.row + cr + 1, ws.col + cc + 1, len, wca, s);
gotorc(cr, cc + len); // Position cursor to end of string
}
/* -- Scroll contents of current window up by the number of lines
specified in nrows. Blanks that many lines at bottom using the current
display attribute. */
void cwindow::scrollUp(int nrows)
{
if (!isOpen) return; // Exit if window is closed
disp_scroll(nrows, ws.row + 1, ws.col + 1, wbr - 1, wrc - 1, wca);
}
/* -- Scroll contents of current window down by the number of lines
specified in nrows. Blanks that many lines at top using the current
display attribute. */
void cwindow::scrollDown(int nrows)
{
if (!isOpen) return; // Exit if window is closed
disp_scroll(-nrows, ws.row + 1, ws.col + 1, wbr - 1, wrc - 1, wca);
}
/* -- Erase from current cursor position to end of line, that is, to
just before the window's right border. Uses the current attribute for
the blanked area. */
void cwindow::eeol(void)
{
unsigned attr = wca * 256 + ' '; // Attribute for blank line
int nc = ws.width - cc - 3; // Number of chars to erase
int acr = ws.row + cr + 1; // Absolute cursor row
int acc = ws.col + cc + 1; // Absolute cursor column
if (!isOpen) return; // Exit if window is closed
if (nc < 0) return; // Exit if no space to cursor's right
disp_fillbox(attr, acr, acc, acr, acc + nc);
}
/* -- Erase from current cursor position to end of window, that is,
to just before the window's bottom border. Uses the current attribute
for the blanked area. */
void cwindow::eeow(void)
{
int ocr = cr; // Save old cr (cursor row)
int occ = cc; // Save old cc (cursor col)
if (!isOpen) return; // Exit if window is closed
eeol(); // Erase to end of current line
while (++cr < ws.height - 2) { // Erase other full lines if any
gotorc(cr, 0);
eeol();
}
cr = ocr; // Restore saved cursor position
cc = occ;
}
// Copyright (c) 1990 by Tom Swan. All rights reserved
// Revision 1.00 Date: 09/22/1990 Time: 12:33 am
// Revision 1.01 Date: 07/08/1991 Time: 05:41 pm
// Converted for Borland C++ 2.0